]> dgit.raspbian.org Git - ostree.git/commit
bootconfig: Preserve extension BLS keys across staged deployments
authorJoseph Marrero Corchado <jmarrero@redhat.com>
Wed, 1 Apr 2026 19:40:45 +0000 (15:40 -0400)
committerJoseph Marrero Corchado <jmarrero@redhat.com>
Thu, 2 Apr 2026 00:52:59 +0000 (20:52 -0400)
commit4affc1bdd5fe1582fcd23d056ae7beb7b8717324
tree2f147d97e9417ebd88e733225890620edba4efa5
parentc13d65041fa9c273720efdd16dc6fd9d2e5ff9e2
bootconfig: Preserve extension BLS keys across staged deployments

When a deployment is staged via ostree_sysroot_stage_tree_with_options(),
the deployment metadata is serialized to /run/ostree/staged-deployment
as a GVariant. During finalization at shutdown,
_ostree_sysroot_reload_staged() creates a fresh OstreeBootconfigParser
and only restores the "options" key from the serialized kargs. Any
additional BLS keys that were set on the bootconfig are silently dropped.

The parse/write/clone paths in OstreeBootconfigParser already handle
unknown keys generically (the "Write unknown fields" loop in
write_at()), so keys survive direct deployments and in-memory
operations. The gap is exclusively in the staged deployment roundtrip,
where a fresh bootconfig is rebuilt from just the kargs strv.

This matters for the upcoming bootc `loader-entries set-options-for-source`
feature, which stores kernel argument ownership as extension BLS keys
(e.g. `x-options-source-tuned nohz=full isolcpus=1-3`). On bootc
systems with transient /etc, tools like TuneD lose track of which kargs
they own because their state files are wiped on reboot. Tracking
ownership directly in the BLS config on /boot solves this, but only if
the keys survive staging. systemd-boot, GRUB, and zipl all ignore
unknown BLS keys, so extension keys are safe.

Fix this by following the same pattern used for overlay-initrds:

1. Add _ostree_bootconfig_parser_get_extra_keys_variant() which returns
   all non-standard BLS keys as an a{ss} GVariant. Standard keys
   (title, version, options, linux, initrd, devicetree) are excluded
   since they are rebuilt from scratch during finalization. All other
   keys are preserved, trusting the caller.

2. In ostree_sysroot_stage_tree_with_options(), serialize any extra
   keys as "bootconfig-extra" in the staged GVariant dict. Since
   _ostree_deployment_set_bootconfig_from_kargs() creates a fresh
   bootconfig with only the "options" key, the code falls back to
   the merge deployment's bootconfig for extra keys. This ensures
   keys are inherited across staged deployments without the caller
   needing to re-set them.

3. In _ostree_sysroot_reload_staged(), restore extra keys from the
   "bootconfig-extra" dict onto the deployment's bootconfig via
   ostree_bootconfig_parser_set().

The function is private (_ostree_ prefix) since only ostree's own
staging code uses it. No new public API, no changes to .sym files,
no changes to GIR or Rust bindings.

Backwards compatibility:
- Old ostree ignores the unknown "bootconfig-extra" key in the a{sv}
  dict (extension keys silently lost, same as before this patch).
- New ostree gracefully handles the absence of "bootconfig-extra" in
  staged data written by older versions (g_variant_dict_lookup returns
  FALSE, no restoration attempted).

Assisted-by: OpenCode (Claude claude-opus-4-6)
Signed-off-by: Joseph Marrero Corchado <jmarrero@redhat.com>
src/libostree/ostree-bootconfig-parser-private.h
src/libostree/ostree-bootconfig-parser.c
src/libostree/ostree-sysroot-deploy.c
src/libostree/ostree-sysroot.c
tests/test-bootconfig-parser-internals.c